package cz.acies.uniql.sql.element;

import org.dom4j.Element;
import org.dom4j.dom.DOMElement;


import cz.acies.uniql.dialect.Dialect;
import cz.acies.uniql.sql.UniQLExpr;

public class UniQLFrom extends UniQLExpr
{
	private static final long serialVersionUID = 5003647575122947978L;
	
	private String alias = null;
	
	/**
	 * Konstruktor tridy UniQLFrom.
	 */
	public UniQLFrom() {
	}

	/**
	 * Konstruktor tridy UniQLFrom.
	 * 
	 * @param dialect - dialect
	 */
	public UniQLFrom(Dialect dialect) {
		super(dialect);
	}

	/**
	 * Konstruktor tridy UniQLFrom.
	 * 
	 * @param expr - expr
	 */
	public UniQLFrom(String expr) {
		super();
		this.parse(expr);
	}

	/**
	 * Konstruktor tridy UniQLFrom.
	 * 
	 * @param tableName - table name
	 * @param alias - alias
	 */
	public UniQLFrom(String tableName, String alias) {
		super();
		this.setName(tableName);
		this.setAlias(alias);
	}

	/**
	 * Konstruktor vytvori nonou instanci objektu UniQLFrom s vlastnostmi
	 * objektu zadaneho jako parametr konstruktoru.
	 *  
	 * @param orderBy
	 */
	public UniQLFrom(UniQLFrom expr) throws Exception {
		this();
		UniQLFrom clone = (UniQLFrom)expr.clone();
		
		setId(clone.getId());
		setName(clone.getName());
		setDialect(clone.getDialect());
		setAliasMap(clone.getAliasMap());
		
		setAlias(clone.getAlias());
	}

	// -----  -----------------------------------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#translate()
	 */
	public String translate() throws Exception {
		Dialect dialect = this.getDialect();
		String schema = dialect.getSchema();
		StringBuffer sb = new StringBuffer("");
		if (getName() != null && getName().length() > 0) {
			if (schema != null && schema.length() > 0) {
				sb.append(dialect.CTI_LQ() + schema + dialect.CTI_RQ() + ".");
			}
			sb.append(dialect.LQ())
				.append(dialect.transferAlias(getName()))
				.append(dialect.RQ());
			if (alias != null && alias.length() > 0) {
				sb.append(""+dialect.getFromAsString()+"").append(alias.toLowerCase());
			}				
		}		
		//System.out.println("UniQLFrom.translate() = "+sb);
		return sb.toString();
	}
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#parse(java.lang.String)
	 */
	public UniQLExpr parse(String expr) {
		int pos = expr.toUpperCase().indexOf(" AS ");
		if (pos > 0) {
			String shl = expr.substring(0, pos);
			this.setName(shl.trim());
			String shr = expr.substring(pos+4, expr.length());
			//System.out.println("");
			this.setAlias(shr.trim());
		} else {
			this.setName(expr.trim());
		}
		return this;
	}
	
	// -----  -----------------------------------------------------------------
	
	/**
	 * Metoda odstran� v�echny doposud p�idan� elementy. Priv�tn� prom�bb� nastav� 
	 * na defauln� hodnoty.
	 *  
	 */
	public UniQLExpr clear() {
		alias = null;
		return this;
	}

	
	/* (non-Javadoc)
	 * @see java.lang.Object#clone()
	 */
	@Override
	public Object clone() throws CloneNotSupportedException {
		Object clone = super.clone();
		assert clone instanceof UniQLFrom;
		((UniQLFrom)clone).setAlias(alias);
		return clone;
	}

	
	// -----  -----------------------------------------------------------------

	/**
	 * Navraci jmeno tabulky.
	 * 
	 * @return - vraci jmeno tabulky
	 */
	public String getTable() {
		return this.getName();
	}

	/**
	 * Zadav� jmeno tabulky.
	 * 
	 */	
	public void setTable(String table) {
		this.setName(table);
	}
	
	// -----  -----------------------------------------------------------------
	
	/**
	 * Navraci hodnotu alias.
	 * 
	 * @return - vraci hodnotu alias
	 */
	public String getAlias() {
		return alias;
	}

	/**
	 * Zadava hodnotu alias.
	 * 
	 * @param alias - alias
	 * 
	 * @return vraci objekt typu UniQLFrom
	 */
	public UniQLFrom setAlias(String alias) {
		this.alias = alias;
		return this;
	}

	/**
	 * Zadava hodnotu alias
	 * 
	 * @param alias - alias
	 * 
	 * @return vraci objekt typu UniQLFrom
	 */
	public UniQLFrom as(String alias) {
		this.alias = alias;
		return this;
	}

	// -----  -----------------------------------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#transToXML()
	 */
	public String transToXML() throws Exception {
		DOMElement node = new DOMElement("UniQLFrom");
		transToXML(node);
		return node.asXML();
	}
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#transToXML(org.dom4j.dom.DOMElement)
	 */
	public DOMElement transToXML(DOMElement node) throws Exception {
		node.setName("UniQLFrom");
		String table = this.getName();
		if (table != null && table.length() > 0) {
			node.setAttribute("table", table.toLowerCase());
		}
		if (alias != null && alias.length() > 0) {
			node.setAttribute("alias", alias);
		}
		return node;
	}
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#xmlToExpr(java.lang.String)
	 */
	public UniQLExpr xmlToExpr(String xml) throws Exception {
		System.out.println("UniQLFrom.xmlToExpr(xml)");
		return null;
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.sql.UniQLExpr#xmlToExpr(org.dom4j.Element)
	 */
	public UniQLExpr xmlToExpr(Element node) throws Exception {
		String table = node.attributeValue("table");
		if (table != null && table.length() > 0) {
			this.setName(table);
		}
		String alias = node.attributeValue("alias");
		if (alias != null && alias.length() > 0) {
			this.setAlias(alias);
		}
		return this;
	}
	
	// -----  -----------------------------------------------------------------

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		Dialect dialect = this.getDialect();
		String schema = "";
		if (dialect.getSchema() != null) schema = dialect.getSchema();
		return "UniQLFrom( schema="+schema+", table="+this.getName()+", alias="+alias+" )";
	}
	/*
	public int hashCode() {
		int hash = -1; 
		if (this.getName() != null) hash = this.getName().hashCode();
		//if (this.getAlias() != null) hash += this.getAlias().hashCode();
		return hash; 
	}
	*/
};